package errors

import (
	"bytes"
	e "errors"
	"fmt"
)

const (
	MBR_INVAID                = `无效的会员`
	ORDER_MAKE_FAILED         = "无效的商品或订单创建失败"
	ORDER_NOT_FOUND           = "订单获取失败"
	POINT_OR_GOODS_NOT_ENOUGH = "积分或商品库存不够"
	CHARGE_FAILED             = "支付失败"
)

type Error interface {
	Name() string
	Error() string
	Append(key string, value interface{}) Error
	Level() int
	Format() string
}

type errorImpl struct {
	name string
	err  error
	data map[string]interface{}
}

func (err *errorImpl) Name() string {
	return err.name
}

func (err *errorImpl) Error() string {
	return err.err.Error()
}

func (err *errorImpl) Append(key string, value interface{}) Error {
	err.data[key] = value
	return err
}

func (err *errorImpl) Level() int {
	return 3
}

func (err *errorImpl) Format() string {
	var buffer bytes.Buffer
	for k, v := range err.data {
		buffer.WriteString(fmt.Sprintf("<%s", k))
		buffer.WriteString(":")
		buffer.WriteString(fmt.Sprintf("%v", v))
		buffer.WriteString(">")
	}

	return fmt.Sprintf("%s::%s::%s", err.Name(), buffer.String(), err.err.Error())
}

func New(name, text string) Error {
	return &errorImpl{name: name, err: e.New(text), data: make(map[string]interface{})}
}

func Raw(text string) error {
	return e.New(text)
}

func Null() Error {
	return nil
}
